package com.xkcoding.elasticsearch.config;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;

/**
 * @Author: dengkaibing
 * @Description:
 * @Date: 2022/2/21 17:26
 * @company 翼支付
 */
@Component
@Slf4j
public class EsUtils {

    /**
     * 私有构造方法
     */
    private EsUtils() {
    }

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    private static RestHighLevelClient client;

    /**
     * spring容器初始化的时候执行该方法
     */
    @PostConstruct
    public void initClient() {
        client = this.restHighLevelClient;
    }
    /**
     * 创建索引以及映射mapping，并给索引某些字段指定iK分词，以后向该索引中查询时，就会用ik分词。
     * 商户索引
     * @param: indexName  索引，类似数据库
     * @return: boolean
     */
    public static boolean createMerchantIndex(String indexName) {

        CreateIndexResponse createIndexResponse = null;
        try {
            //创建映射
            XContentBuilder mapping = null;
            try {
                mapping = XContentFactory.jsonBuilder()
                    .startObject()
                    .field("dynamic", "false")
                    .startObject("properties")
                    .startObject("bestpayNo")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("merchantId")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("merchantName")
                    .field("type", "text")
                    .endObject()
                    .startObject("merchantAbbr")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("merchantType")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("merchantRequest")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("businessAddr")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("businessTime")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("provinceName")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("provinceCode")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("cityName")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("cityCode")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("districtName")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("districtCode")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("delFlag")
                    .field("type", "boolean")
                    .endObject()
                    .startObject("bankAccount")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("bankAcrd")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("bankName")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("businessScope")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("platformNumber")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("contactPerson")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("mobile")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("email")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("businessLicenseId")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("businessLicenseImg")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("distributorId")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("agreeStatusDate")
                    .field("type", "date")
                    .field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
                    .endObject()
                    .startObject("bankConnectionDesensitize")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("merchantStatus")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("createdBy")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("updatedBy")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("createdAt")
                    .field("type", "date")
                    .field("format","yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
                    .endObject()
                    .startObject("updatedAt")
                    .field("type", "date")
                    .field("format","yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
                    .endObject()
                    .endObject()
                    .endObject();
                log.info("createIndex builder:{}", mapping);
            } catch (IOException e) {
                e.printStackTrace();
            }
            CreateIndexRequest request = new CreateIndexRequest(indexName).source(mapping);
            request.mapping(mapping);
            request.alias(new Alias("mall-data-service_merchant"));
            //设置创建索引超时2分钟
            request.setTimeout(TimeValue.timeValueMinutes(2));
            request.settings(Settings.builder()
                .put("index.number_of_shards", 3)
                .put("index.number_of_replicas", 2)
            );
            createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (createIndexResponse == null) {
            return Boolean.FALSE;
        }
        return createIndexResponse.isAcknowledged();
    }
    /**
     * 判断索引是否存在
     *
     * @param index 索引，类似数据库
     * @return boolean
     */
    public static boolean isIndexExist(String index) {
        boolean exists = false;
        try {
            exists = client.indices().exists(new GetIndexRequest(index), RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (exists) {
            log.info("Index [{}] is exist!", index);
        } else {
            log.info("Index [{}] is not exist!", index);
        }
        return exists;
    }
    /**
     * 数据添加
     *
     * @param content   要增加的数据
     * @param indexName 索引，类似数据库
     * @param id        id
     * @return String
     */
    public static String addData(String content, String indexName, String id)  {
        IndexResponse response;
        IndexRequest request = new IndexRequest(indexName).id(id);
        request.source(content, XContentType.JSON);
        try {
            log.info("addData,rq:{}", content);
            response = client.index(request, RequestOptions.DEFAULT);
            return response.getId();
        } catch (IOException e) {
            log.error("updateData error,e:", e);
            e.printStackTrace();
        }
        return "";
    }
}
